package club.xyes.zkh.ecommerce.service;

import club.xyes.zkh.ecommerce.commons.dto.Tuple2;
import club.xyes.zkh.ecommerce.commons.entity.Coupon;
import club.xyes.zkh.ecommerce.commons.entity.Shop;
import club.xyes.zkh.ecommerce.commons.entity.User;
import club.xyes.zkh.ecommerce.commons.entity.UserCoupon;
import club.xyes.zkh.ecommerce.commons.exception.DiscountException;
import club.xyes.zkh.ecommerce.service.listener.OnCouponGrantListener;

import java.util.List;

/**
 * Create by 郭文梁 2019/4/18 0018 13:40
 * UserCouponService
 * 用户优惠券关系业务服务行为定义
 *
 * @author 郭文梁
 * @data 2019/4/18 0018
 */
public interface UserCouponService extends BaseService<UserCoupon> {
    /**
     * 根据用户ID查询用户所拥有的优惠券，同事关联查询出优惠券的详情
     *
     * @param userId 用户ID
     * @return Coupon List
     */
    List<UserCoupon> findByUserIdFetchAll(Integer userId);

    /**
     * 获取优惠金额
     *
     * @param id                    用户优惠券ID
     * @param user                  用户
     * @param shop                  商铺
     * @param fee                   应付金额
     * @return (y用户优惠券信息, 优惠金额)
     * @throws DiscountException 指定的优惠方式存在逻辑错误
     */
    Tuple2<UserCoupon, Integer> getDiscount(Integer id, User user, Shop shop, Integer fee) throws DiscountException;

    /**
     * 根据ID查询对象 同时查询关联属性
     *
     * @param id ID
     * @return 查询结果对象
     */
    UserCoupon getFetchAll(Integer id);

    /**
     * 根据ID查询对象 同时查询关联属性
     * 若结果为空， 则抛出异常
     *
     * @param id ID
     * @return 查询结果对象
     */
    UserCoupon getFetchAllRequired(Integer id);

    /**
     * 设置用户优惠券状态
     *
     * @param userCoupon 用户优惠券
     * @param status     状态
     */
    void setStatus(UserCoupon userCoupon, int status);

    /**
     * 获取用户在某商铺
     *
     * @param user          用户
     * @param shop          商铺
     * @param fee           消费金额
     * @param useMembership 是否已使用会员
     * @return 优惠券列表
     */
    List<UserCoupon> available(User user, Shop shop, int fee, boolean useMembership);

    /**
     * 通过用户和商铺查找会员信息
     *
     * @param user 用户
     * @param shop 商铺
     * @return 会员信息
     */
    List<UserCoupon> findByUserAndShop(User user, Shop shop);

    /**
     * 用户领取优惠券
     *
     * @param user   用户
     * @param coupon 优惠券ID
     * @return UserCoupon
     */
    UserCoupon take(User user, Coupon coupon);

    /**
     * 自动发放优惠券
     *
     * @param user           被发放用户
     * @param amount         用户本次消费金额
     * @param shop           商铺
     * @param matchedCoupons 匹配的优惠券
     * @param listener       发放成功监听器
     * @return 发放结果
     */
    List<UserCoupon> autoGrant(User user, Shop shop, List<Coupon> matchedCoupons, int amount, OnCouponGrantListener listener);

    /**
     * 通过用户和商铺查询数量
     *
     * @param userId 用户ID
     * @param shopId 商铺ID
     * @return 数量
     */
    int countByUserAndShop(Integer userId, Integer shopId);

    /**
     * 群发优惠券
     *
     * @param coupon     优惠券
     * @param userIdList 用户ID列表
     * @param shop       商铺信息
     * @param users      用户
     * @param listener   发放成功监听器
     * @return userCoupon list
     */
    List<UserCoupon> grant(Coupon coupon,
                           Shop shop,
                           List<Integer> userIdList,
                           List<User> users,
                           OnCouponGrantListener listener);
}
